package com.web.exiaodao.remote.controller;

import com.alibaba.fastjson.JSON;
import com.google.common.base.Function;
import com.google.common.collect.Maps;
import com.web.exiaodao.business.constant.JConstant;
import com.web.exiaodao.business.entity.Order;
import com.web.exiaodao.business.entity.Returnshoprecord;
import com.web.exiaodao.business.entity.User;
import com.web.exiaodao.remote.service.*;
import com.web.exiaodao.remote.vo.*;
import com.web.webstart.base.constant.XaConstant;
import com.web.webstart.base.controller.BaseController;
import com.web.webstart.base.exception.BusinessException;
import com.web.webstart.base.util.DateUtils;
import com.web.webstart.base.util.Identities;
import com.web.webstart.base.util.Validator;
import com.web.webstart.base.util.XaUtil;
import com.web.webstart.base.util.jpa.WebUitl;
import com.web.webstart.base.util.result.XaResult;
import com.wordnik.swagger.annotations.Api;
import com.wordnik.swagger.annotations.ApiOperation;
import com.wordnik.swagger.annotations.ApiParam;
import org.apache.log4j.Logger;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.*;

/**
 * @author zhanglin
 * @version V1.0
 * @Title: ApiOrderController.java
 * @Package com.web.exiaodao.remote.controller
 * @Description: 商品-订单表信息接口
 * @date 2016-11-03 10:54:30
 */
@Api(value = "Order", description = "订单表接口", position = 10)
@Controller
@RequestMapping("/api/order")
public class ApiOrderController extends BaseController {

    private static final Logger LOGGER = Logger.getLogger(ApiOrderController.class);

    @Autowired
    private ApiUserService userService;

    @Autowired
    private ApiServiceNurseTrainingService nurseTrainingService;

    @Autowired
    private ApiOrderService orderService;

    @Autowired
    private ApiShopService shopService;

    @Autowired
    private ApiInsHotelRoomsTableService insHotelRoomsTableService;

    @Autowired
    private ApiExchangeProductsService exchangeProductsService;

    @Autowired
    private ApiAddressService addressService;

    //退款记录
    @Autowired
    private ApiReturnshoprecordService returnshoprecordService;

    /**
     * @return
     * @Title: save
     * @Description: 服务类下单
     */
    @ApiOperation(value = "预订(服务;景点|游学|旅游;住|机构|酒店|学乐,玩)接口", notes = "服务类下单,当返回的code=1时，保存成功后object返回对象")
    @ResponseBody
    @RequestMapping(value = "saveServiceOrder", method = RequestMethod.POST)
    public XaResult<OrderVo> saveServiceOrder(
            @ApiParam("购买人ID,字段名:userId") @RequestParam(value = "userId") Long userId,
            @ApiParam("订单类型(3：玩 /达人/作品/艺术品 ；51:住； 52:机构参观  53：旅游/游学     62:家政护理<取消>; 63:医疗服务|医疗康复<取消>; 64:护理培训|培训义工),字段名:order_type") @RequestParam(value = "order_type") Integer order_type,
            @ApiParam("服务类专用-对象Id,字段名:service_object_id(服务id;景点id;酒店id)") @RequestParam(value = "service_object_id") Long service_object_id,
            @ApiParam("服务类专用-商品数量/房间数量,字段名:service_num") @RequestParam(value = "service_num", required = false, defaultValue = "1") Long service_num,
            @ApiParam("服务类专用-单价,字段名:service_price") @RequestParam(value = "service_price") Double service_price,
            @ApiParam("服务类专用-联系人,字段名:service_userName") @RequestParam(value = "service_userName", required = false) String service_userName,
            @ApiParam("服务类专用-手机号,字段名:service_phone") @RequestParam(value = "service_phone", required = false) String service_phone,
            @ApiParam("服务专用-预约服务时间,参观时间(yyyy-MM-dd HH:mm),字段名:service_appointment_time") @RequestParam(value = "service_appointment_time", required = false, defaultValue = "") String service_appointment_time,
            @ApiParam("服务类专用-身份证号/护照,字段名:service_idCard") @RequestParam(value = "service_idCard", required = false, defaultValue = "") String service_idCard,
            @ApiParam("积分或者亲和币抵的数额;亲币数量或者积分数量),字段名:deducted_money") @RequestParam(value = "deducted_money", required = false, defaultValue = "0") Integer deducted_money,
            @ApiParam("邮费，默认0.00,字段名:postage") @RequestParam(value = "postage", required = false, defaultValue = "0") Double postage,
            @ApiParam("机构专用-参观目的,字段名:insVisitPurpose") @RequestParam(value = "insVisitPurpose", required = false) String insVisitPurpose,
            @ApiParam("机构专用-参观公司,字段名:insVisitCompany") @RequestParam(value = "insVisitCompany", required = false) String insVisitCompany,
            @ApiParam("酒店专用-入住时间,格式:yyyy-MM-DD字段名:hourse_checkinTime") @RequestParam(value = "hourse_checkinTime", required = false) String hourse_checkinTime,
            @ApiParam("酒店专用-入住时长(单位：天,月),字段名:hourse_checkin_duration") @RequestParam(value = "hourse_checkin_duration", required = false, defaultValue = "1") Integer hourse_checkin_duration,
            @ApiParam("酒店专用-入住时长单位(耽误:天,月),字段名:hourse_checkin_duration_unit") @RequestParam(value = "hourse_checkin_duration_unit", required = false) String hourse_checkin_duration_unit,
            @ApiParam("订单总价（商品总价+运费-抵扣）,字段名:payment_Cost") @RequestParam(value = "payment_Cost", required = false, defaultValue = "0") Double payment_Cost,
            @ApiParam("地址Id,字段名:addressId") @RequestParam(value = "addressId", required = false) Long addressId,
            HttpServletRequest request
    ) throws BusinessException {
        XaResult<OrderVo> xr = new XaResult<>();
        if (XaUtil.isEmpty(userId)) {
            xr.error("用户Id不能为空！");
            return xr;
        }
        if (XaUtil.isEmpty(order_type)) {
            xr.error("订单类型不能为空！");
            return xr;
        }
        if (!JConstant.Order_CommentType.isConstantVal(order_type)) {
            xr.error("订单类型错误！");
            return xr;
        }
        if (XaUtil.isEmpty(service_object_id)) {
            xr.error("对象Id不能为空！");
            return xr;
        }
        if (XaUtil.isEmpty(service_num)) {
            xr.error("订单数量不能为空！");
            return xr;
        }
        if (XaUtil.isEmpty(service_price)) {
            xr.error("商品价格(单价)不能为空！");
            return xr;
        }
        if (XaUtil.isNotEmpty(service_phone) && XaUtil.isEmpty(service_phone)) {
            xr.error("联系人手机号不能为空！");
            return xr;
        }
        if (XaUtil.isNotEmpty(service_phone) && !Validator.isMobile(service_phone)) {
            xr.error("手机号码格式不正确");
            return xr;
        }
        if (XaUtil.isNotEmpty(service_appointment_time)) {
            if (!Validator.isDateToMin(service_appointment_time)) {
                xr.error("日期格式不正确(yyyy-MM-dd HH:mm)");
                return xr;
            }
            Date appointDate = DateUtils.formatStr(service_appointment_time, DateUtils.YYYYMMDDHHMM);
            if (new Date().compareTo(appointDate) > 1) {
                xr.error("预约日期已过,请重新输入");
                return xr;
            }
        }
        if (XaUtil.isNotEmpty(service_idCard)) {
            boolean isVal = Validator.isIDCard(service_idCard);
            if (!isVal) {
                if (service_idCard.length() > 50) {
                    isVal = false;
                } else {
                    isVal = true;
                }
            }
            if (!isVal) {
                xr.error("身份证/护照格式不正确");
                return xr;
            }
        }
        if (order_type == JConstant.Order_CommentType.INSTIBUTION_VISITING) {
            if (service_num != 1) {
                xr.error("机构参观:订单数量错误");
                return xr;
            }
        }
        if (order_type == JConstant.Order_CommentType.HOURSE) {
            InsHotelRoomsTableVo vo = insHotelRoomsTableService.findOne(service_object_id).getObject();
            if (order_type == JConstant.Order_CommentType.HOURSE && (vo != null && !vo.getIsSellByCard())) {//酒店
                if (XaUtil.isEmpty(hourse_checkinTime)) {
                    xr.error("入住时间不能为空");
                    return xr;
                }
                if (!Validator.isDate(hourse_checkinTime)) {
                    xr.error("入住时间格式不正确(yyyy-MM-dd)");
                    return xr;
                }
                if (XaUtil.isEmpty(hourse_checkin_duration)) {
                    xr.error("入住时间时长不能为空)");
                    return xr;
                }
                Date checkInDate = DateUtils.formatStr(hourse_checkinTime, DateUtils.YYYYMMDD);
                Date nowDate = new Date(new GregorianCalendar().get(Calendar.YEAR), new GregorianCalendar().get(Calendar.MONTH), new GregorianCalendar().get(Calendar.DAY_OF_MONTH));
                if (nowDate.compareTo(checkInDate) != 1) {
                    xr.error("入住日期已过,请重新输入");
                    return xr;
                }
                if (XaUtil.isEmpty(hourse_checkin_duration_unit)) {
                    xr.error("入住时间时长单位不能为空)");
                    return xr;
                }
                if (!(hourse_checkin_duration_unit.equals("月") || hourse_checkin_duration_unit.equals("天") || hourse_checkin_duration_unit.equals("季") || hourse_checkin_duration_unit.equals("年"))) {
                    xr.error("入住时间时长单位不正确,只能为:(天，月，季，年))");
                    return xr;
                }
            }
            if (hourse_checkin_duration <= 0) {
                xr.error("入住时间时长不能小1)");
                return xr;
            }
        }
        //验证用户
        userService.findOne(userId);

        //验证对象id
        if (order_type == JConstant.Order_CommentType.SERVICE_NURSE_TRANING) {//64
            ServiceNurseTrainingVo nurseTraining = nurseTrainingService.findOne(service_object_id).getObject();
            int inventory = nurseTraining.getQuantityInventory();
            if (inventory <= 0) {
                xr.error("报名人数已满");
                return xr;
            }
            if (payment_Cost == 0) payment_Cost = service_num * service_price;
            //判断时间
            Date startTime = DateUtils.formatStr(nurseTraining.getOrderStartTime(), DateUtils.YYYYMMDDHHMM);
            Date endTime = DateUtils.formatStr(nurseTraining.getOrderEndTime(), DateUtils.YYYYMMDDHHMM);
            Date nowDate = new Date();
            if (nowDate.compareTo(startTime) != 1) {
                xr.error("报名还没开始");
                return xr;
            }
            if (nowDate.compareTo(endTime) != -1) {
                xr.error("报名时间已经截止");
                return xr;
            }
        }

        //验证收货地址
        AddressVo addressVo = null;
        if (XaUtil.isNotEmpty(addressId)) {
            addressVo = addressService.findOne(addressId).getObject();
            if (addressVo.getUserId().longValue() != userId) {
                xr.error("收货地址有误,请选择自己的收货地址!");
                return xr;
            }
        }

        Order model = new Order();
        model.setUserId(userId);
        model.setOrderType(order_type + "");
        model.setService_object_id(service_object_id);
        model.setService_num(service_num);
        model.setService_price(service_price);
        model.setService_userName(service_userName);
        model.setService_phone(service_phone);
        model.setService_idCard(service_idCard);
        model.setService_appointment_time(service_appointment_time);
        model.setOrderNo(Identities.getRandomOrderNo());
        model.setPostage(postage);
        model.setInsVisitCompany(insVisitCompany);
        model.setInsVisitPurpose(insVisitPurpose);
        model.setHourse_checkinTime(hourse_checkinTime);
        model.setHourse_checkin_duration(hourse_checkin_duration);
        model.setHourse_checkin_duration_unit(hourse_checkin_duration_unit);
        model.setDeducted_money(deducted_money);//抵扣价格
        model.setOrderTotalPirce(payment_Cost);//最终价格
        model.setAddressInfo(addressVo);
        model.setOrderState(JConstant.OrderStatus.UN_PAY + "");

        return orderService.saveSericeOrder(model);
    }


    /**
     * @return
     * @Title: save
     * @Description: 兑换商品下单
     */
    @ApiOperation(value = "兑换商品下单", notes = "兑换商品下单,当返回的code=1时，保存成功后object返回对象")
    @ResponseBody
    @RequestMapping(value = "saveExchangeOrder", method = RequestMethod.POST)
    public XaResult<OrderVo> saveExchangeOrder(
            @ApiParam("购买人ID,字段名:userId") @RequestParam(value = "userId") Long userId,
            @ApiParam("对象Id,字段名:service_object_id(兑换商品id)") @RequestParam(value = "service_object_id") Long service_object_id,
            @ApiParam("地址Id,字段名:addressId") @RequestParam(value = "addressId") String addressId,
            @ApiParam("商品数量,字段名:service_num") @RequestParam(value = "service_num", required = false, defaultValue = "1") Long service_num,
            @ApiParam("邮费，默认0.00,字段名:postage") @RequestParam(value = "postage", required = false, defaultValue = "0") Double postage,
            HttpServletRequest request
    ) throws BusinessException {
        XaResult<OrderVo> xr = new XaResult<>();
        if (XaUtil.isEmpty(userId)) {
            xr.error("用户Id不能为空！");
            return xr;
        }
        if (XaUtil.isEmpty(service_object_id)) {
            xr.error("对象Id不能为空！");
            return xr;
        }

        //验证用户
        userService.findOne(userId).getObject();

        ExchangeProductsVo exchangeProductsVo = exchangeProductsService.findOne(service_object_id).getObject();
        int deducted_money = (int) (service_num * Integer.parseInt(exchangeProductsVo.getNeedCoins()));

        //验证收货地址
        AddressVo addressVo = addressService.findOne(Long.parseLong(addressId)).getObject();
        if (addressVo.getUserId().longValue() != userId) {
            xr.error("收货地址有误,请选择自己的收货地址!");
            return xr;
        }

        Order model = new Order();
        model.setUserId(userId);
        model.setOrderNo(Identities.getRandomOrderNo());
        model.setPostage(postage);
        model.setAddressInfo(addressVo);
        model.setDeducted_money(deducted_money);//抵扣的亲币数量
        model.setAddressId(addressId);
        model.setService_object_id(service_object_id);
        model.setOrderType(JConstant.Order_CommentType.GOODS_EXCHANGE + "");
        model.setOrderState(JConstant.OrderStatus.UN_PAY + "");
        model.setService_num(service_num);
        return orderService.saveSericeOrder(model);
    }

    /**
     * @return
     * @Title: save
     * @Description: 普通商品下单(单价商品下单, 购物车下单 同一个订单号)
     */
    @ApiOperation(value = "普通商品下单", notes = "普通商品下单,当返回的code=1时，保存成功后object返回对象")
    @ResponseBody
    @RequestMapping(value = "saveShopOrder", method = RequestMethod.POST)
    public XaResult<OrderVo> saveShopOrder(
            @ApiParam("购买人ID,字段名:userId") @RequestParam(value = "userId") Long userId,
            @ApiParam("地址Id,字段名:addressId") @RequestParam(value = "addressId") Long addressId,
            @ApiParam("商品信息,json字符串,字段名:shopInfo,格式:[{\"shopId\":1, \"carNumber\":2, \"standardIds\":\"1,3\"},{\"shopId\":11, \"carNumber\":22, \"standardIds\":\"11,33\"}]") @RequestParam(value = "shopCarInfo") String shopInfo,
            @ApiParam("购物车Id集合,字段名:carIds,如果从购物车下单此字段传购物车Id，以逗号分隔，否则该字段为空") @RequestParam(required = false, defaultValue = "") String carIds,
            @ApiParam("邮费，默认0.00,字段名:postage") @RequestParam(value = "postage", required = false, defaultValue = "0") Double postage,
            @ApiParam("积分或者亲和币抵扣金额(亲币数量或者积分数量),字段名:deducted_money") @RequestParam(value = "deducted_money", required = false, defaultValue = "0") Integer deducted_money,
            @ApiParam("种类(种类)（1：个人，2：公司）,字段名:billType") @RequestParam(value = "billType", required = false) Integer billType,
            @ApiParam("种类(种类)（1：纸质发票 2:电子发票）,字段名:billEtype") @RequestParam(value = "billEtype", required = false) Integer billEtype,
            @ApiParam("抬头,字段名:billTitle") @RequestParam(value = "billTitle", required = false) String billTitle,
            @ApiParam("发票内容(预留),如:明细;食品,字段名:billContent") @RequestParam(value = "billContent", required = false) String billContent,
            HttpServletRequest request
    ) throws BusinessException {
        XaResult<OrderVo> xr = new XaResult<OrderVo>();
        if (XaUtil.isEmpty(userId)) {
            xr.error("用户Id不能为空！");
            return xr;
        }
        if (XaUtil.isEmpty(addressId)) {
            xr.error("地址id不能为空!");
            return xr;
        }
        if (XaUtil.isEmpty(shopInfo)) {
            xr.error("商品信息不能为空！");
            return xr;
        }
        if (XaUtil.isNotEmpty(billType)) {
            if (billType != 1 && billType != 2) {
                xr.error("发票类型只能为1,2！");
                return xr;
            }
            if (XaUtil.isEmpty(billTitle)) {
                xr.error("发票抬头不能为空！");
                return xr;
            }
        }
        //将商品信息字符串转化为对象集合
        List<ShopCarVo> cars = new ArrayList<>();
        try {
            cars = JSON.parseArray(shopInfo, ShopCarVo.class);
        } catch (Exception e) {
            xr.error("json格式不正确或数据格式不正确!");
            return xr;
        }
        if (XaUtil.isEmpty(cars)) {
            xr.error("购买商品不能为空");
            return xr;
        }
        if (cars.size() >= 1) {
            if (XaUtil.isEmpty(carIds)) {
                xr.error("购物车信息不能为空");
                return xr;
            }
            carIds = carIds.replace(JConstant.SYMBOL_DOT_CN, JConstant.SYMBOL_DOT);
            if (carIds.split(JConstant.SYMBOL_DOT).length != cars.size()) {
                xr.error("carIds和shopInfo不匹配!");
                return xr;
            }
        }
        //验证信息
        UserVo userVo = userService.findOne(userId).getObject();
        AddressVo addressVo = addressService.findOne(addressId).getObject();
        if (addressVo.getUserId().longValue() != userId) {
            xr.error("收货地址有误,请选择自己的收货地址!");
            return xr;
        }
        XaResult<Set<Long>> shopIdSetXr = shopService.validateShopInfo(cars, XaUtil.getBool(userVo.getVip()));
        if (!(shopIdSetXr.getObject() instanceof Set)) {
            xr.error(shopIdSetXr.getMessage());
            return xr;
        }

        Order order = new Order();
        order.setUserId(userId);
        order.setAddressInfo(addressVo);
        order.setPostage(postage);
        order.setOrderType(JConstant.Order_CommentType.GOODS + "");
        order.setOrderState(JConstant.OrderStatus.UN_PAY + "");
        order.setOrderNo(Identities.getRandomOrderNo());
        order.setDeducted_money(deducted_money);//抵扣的亲币数量
        //发票消息
        order.setBillType(billType);
        order.setBillEtype(billEtype);
        order.setBillTitle(billTitle);
        order.setBillContent(billContent);

        //获取所有商品的信息
        Pageable pageable = WebUitl.buildPageRequest(0, Integer.MAX_VALUE, "[{property:'createTime',direction:'DESC'}]");
        Map<String, Object> filterParams = WebUitl.getParametersStartingWith("{'search_IN_id':'" + JSON.toJSONString(shopIdSetXr.getObject()) + "'}", "search_");
        List<ShopVo> shopVos = shopService.findListEQStatusByFilter(XaConstant.Status.publish, filterParams, pageable).getObject();
        Map<Long, ShopVo> shopMap = Maps.uniqueIndex(shopVos, new Function<ShopVo, Long>() {
            @Override
            public Long apply(ShopVo shopVo) {
                return shopVo.getId();
            }
        });

        //封装订单详情集合
        Double totalPrice = 0.0;
        List<OrderDetailVo> orderDetails = new ArrayList<>();
        for (ShopCarVo car : cars) {
            OrderDetailVo detail = new OrderDetailVo();
            detail.setShop_ProductSPU(car.getShopId() + "");
            detail.setStandardValues(car.getStandardIds());
            detail.setProductNum(car.getCarNumber());

            ShopVo shopTempVo = shopMap.get(car.getShopId());
            //价格
            boolean isVip = XaUtil.getBool(userVo.getVip());
            double  price = isVip ? Double.parseDouble(shopTempVo.getShopProductPrice()) : Double.parseDouble(shopTempVo.getOriginalPrice());//购买的价格
            if (XaUtil.isNotEmpty(car.getPrice())) {
                detail.setProductOrderPrice(car.getPrice());
            } else {
                car.setPrice(price);
            }
            //名称
            detail.setShopName(shopTempVo.getShopProductName());
            //主图片
            if (XaUtil.isNotEmpty(shopTempVo.getShopProductPicUrls()) && shopTempVo.getShopProductPicUrls().contains(JConstant.SYMBOL_DOT)) {
                detail.setShopUrl(shopTempVo.getShopProductPicUrls().split(JConstant.SYMBOL_DOT)[0]);
            }
            //抵扣比例
            detail.setShopDisCountRate(shopTempVo.getDiscountRate());
            //
            detail.setProductOrderPrice(price);//Double.parseDouble(shopTempVo.getShopProductPrice())
            detail.setShopOriginalPrice(Double.parseDouble(shopTempVo.getOriginalPrice()));

            orderDetails.add(detail);
            totalPrice += (car.getCarNumber() * car.getPrice());
        }
        BigDecimal b1 = new BigDecimal(totalPrice);
        //保留两位小数
        double f3 = b1.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
        order.setGoodsTotalPrices(f3);    //商品订单的价格是改订单下所有商品价格的总和

        return orderService.saveShopOrder(order, orderDetails, carIds);
    }

    /**
     * @Title: 成为vip账户充值生成订单
     * @return
     */
    @ApiOperation(value="saveVipOrder",notes="成为vip账户充值生成订单,当返回的code=1时，保存成功后object返回对象")
    @ResponseBody
    @RequestMapping(value="saveVipOrder",method=RequestMethod.POST)
    public XaResult<UserVo> saveVipOrder (
            @ApiParam("用户ID,字段名:userId") @RequestParam(value = "userId") Long userId,
            HttpServletRequest request
    ) throws Exception{
        XaResult<UserVo> xr = new XaResult<>();
        if (XaUtil.isEmpty(userId)) {
            xr.error("userId不能为空！");
            return xr;
        }
        UserVo userVo = userService.findOne(XaUtil.getNutNullLong(userId, 0l)).getObject();
        boolean isVip = XaUtil.getBool(userVo.getVip());
        if (isVip) {
            xr.error("您已经是vip账号请不要重复充值！");
            return xr;
        }
        String vipOrder = Identities.getVipOrderNo();
        userVo.setVipOrderNo(vipOrder);
        userVo = userService.updateModel(JSON.parseObject(JSON.toJSONString(userVo), User.class)).getObject();
        xr.setObject(userVo);
        return xr;
    }


    /**
     * @param request 操作一个实体状态,根据status进行操作
     * @param orderNo 操作类型:-1锁定,0无效,1正常,2发布,3删除,默认删除操作
     * @return
     * @throws BusinessException
     * @Title: operateOrderById
     */
    @ApiOperation(value = "删除订单", notes = "删除订单(只有交易成功或者交易关闭的订单才可以删除),当返回的code=1时，保存成功后object返回对象")
    @ResponseBody
    @RequestMapping(value = "deleteOrderByOrderNo", method = RequestMethod.POST)
    public XaResult<OrderVo> deleteOrderById(
            HttpServletRequest request,
            @ApiParam("订单id,多个订单用逗号分割,字段名:orderNo,必填") @RequestParam(value = "orderNo") String orderNo
    ) throws BusinessException {
        XaResult<OrderVo> xr = new XaResult<OrderVo>();
        if (XaUtil.isEmpty(orderNo)) {
            xr.error("订单不能为空");
            return xr;
        }
        orderNo = orderNo.replace(JConstant.SYMBOL_DOT_CN, JConstant.SYMBOL_DOT);
        return orderService.multiOperate(orderNo, XaConstant.Status.delete);
    }

    /**
     * @param orderNo
     * @return
     * @Title: cancelOrder
     * @Description: 取消订单
     */
    @ApiOperation(value = "取消订单", notes = "取消订单,当返回的code=1时，取出object进行显示,存放为单体对象")
    @ResponseBody
    @RequestMapping(value = "cancelOrder", method = RequestMethod.POST)
    public XaResult<Boolean> cancelOrder(
            @ApiParam("订单编号,字段名:orderNo,必填") @RequestParam(value = "orderNo") String orderNo
    ) throws BusinessException {
        XaResult<Boolean> xrr = new XaResult<>();
        orderService.cancelOrder(orderNo);
        xrr.setObject(true);
        return xrr;
    }

    /**
     * @param orderNo
     * @return
     * @Title: cofirmRevice
     * @Description: 确认收货
     */
    @ApiOperation(value = "确认收货(仅限商品订单)", notes = "确认收货,当返回的code=1时，取出object进行显示,存放为单体对象")
    @ResponseBody
    @RequestMapping(value = "cofirmRevice", method = RequestMethod.POST)
    public XaResult<OrderVo> cofirmRevice(
            @ApiParam("订单编号,字段名:orderNo,必填") @RequestParam(value = "orderNo") String orderNo
    ) throws BusinessException {
        XaResult<OrderVo> xr = new XaResult<OrderVo>();
        return orderService.cofirmRevice(orderNo);
    }

    /**
     * 查询所有的订单信息
     *
     * @param userId
     * @param orderState {@link JConstant.OrderStatus}
     * @param nextPage
     * @param pageSize
     * @return
     * @throws BusinessException
     */
    @ApiOperation(value = "查询订单信息列表", notes = "查询所有的订单信息,当返回的code=1时，取出object进行显示,存放为数组对象")
    @ResponseBody
    @RequestMapping(value = "findOrderList", method = RequestMethod.POST)
    public XaResult<List<OrderVo>> findOrderList(
            @ApiParam("购买人ID,字段名:userId") @RequestParam(value = "userId") Long userId,
            @ApiParam("订单状态:orderState,多种状态用逗号分隔,0:未支付;1:已支付(待消费、待发货、待入住);2:待收货(没有物流的没有此状态);3:待评价,已经离店;4:已评价(已完成)(交易完成);5:已取消--已失效;(自动,被动)(交易关闭)") @RequestParam(value = "orderState", required = false) String orderState,
            @ApiParam("订单模块:orderType,多种状态用逗号分隔,订单类型(1：普通商品  2:兑换商品  3：玩 /达人/作品/艺术品   51:住； 52:机构参观  53：旅游/游学     62:家政护理; 63:医疗服务|医疗康复; 64:护理培训|培训义工))") @RequestParam(value = "orderType", required = false) String orderType,
            @ApiParam("页号,字段名:nextPage,默认0,从第0页开始") @RequestParam(defaultValue = "0") Integer nextPage,
            @ApiParam("页长,字段名:pageSize,默认10") @RequestParam(defaultValue = "10") Integer pageSize
    ) throws BusinessException {
        XaResult<List<OrderVo>> xr = new XaResult<>();
        if (XaUtil.isEmpty(userId)) {
            xr.error("用户Id不能为空！", true);
            return xr;
        }
        if (XaUtil.isNotEmpty(orderState)) {
            orderState = orderState.replace(JConstant.SYMBOL_DOT_CN, JConstant.SYMBOL_DOT);
        }
        if (XaUtil.isNotEmpty(orderType)) {
            orderType = orderType.replace(JConstant.SYMBOL_DOT_CN, JConstant.SYMBOL_DOT);
        }
        return orderService.getOrders(userId, orderState, orderType, nextPage, pageSize);
    }

    /**
     * @return
     * @Title: findOrderById
     * @Description: 根据ID查找单条实体
     * //@param modelId
     */
    @ApiOperation(value = "订单表详情", notes = "订单表详细信息,当返回的code=1时，取出object进行显示,存放为单体对象")
    @ResponseBody
    @RequestMapping(value = "findOrderById", method = RequestMethod.POST)
    public XaResult<OrderVo> findOrderById(
            @ApiParam("订单编号,字段名:orderNo,必填") @RequestParam(value = "orderNo") String orderNo
    ) throws BusinessException {
        XaResult<OrderVo> xr = new XaResult<OrderVo>();
        return orderService.findDetail(orderNo);
    }

    /**
     * @Title: save
     * @Description: 退货/退货申请
     * 其余逻辑见：微充/ApiReturnShopRecordService
     *
     * 后台逻辑见
     * @see com.web.exiaodao.business.controller.ReturnshoprecordController
     * @return
     */
    @ApiOperation(value="退款/退货申请",notes="退款/退货申请,当返回的code=1时，保存成功后object返回对象")
    @ResponseBody
    @RequestMapping(value="refund",method=RequestMethod.POST)
    public XaResult<ReturnshoprecordVo> saveRefundshoprecord(
            @ApiParam("订单编号,字段名:orderNo") @RequestParam(value = "orderNo") String orderNo,
            @ApiParam("退货类型,字段名:type；0：仅退款  1:退货") @RequestParam(value = "type") Integer type,
            @ApiParam("退货原因,字段名:reason") @RequestParam(value = "reason", required = true) String reason,
            @ApiParam("退货图片,字段名:imgs；多张逗号分割") @RequestParam(value = "imgs", required = false) String imgs,
            HttpServletRequest request
    ) throws Exception{
        XaResult<ReturnshoprecordVo> xr = new XaResult<>();
        if ( !(type == 0 || type == 1) ) {
            xr.error("退货类型不正确!");
            return xr;
        }
        if (XaUtil.isEmpty(reason)) {
            xr.error("退货原因不能为空!");
            return xr;
        }
        Returnshoprecord model = new Returnshoprecord();
        model.setOrderNo(orderNo);
        model.setType(type);
        model.setReason(reason);
        model.setImgs(imgs);
        xr =  returnshoprecordService.createModel(model);
        return xr;
    }

    /**
     * @return
     * @Title: testTransactional
     */
    @ApiOperation(value = "测试Transactional", notes = "测试Transactional,当返回的code=1时")
    @ResponseBody
    @RequestMapping(value = "testTransactional", method = RequestMethod.POST)
    public XaResult<String> testTransactional(
    ) throws BusinessException {
        XaResult<String> xr = new XaResult<>();

        //事物测试，不要删除
        //CglibAopProxy proxy;
        boolean isAopProxy        =  AopUtils.isAopProxy(orderService);
        boolean isCglibProxy      =  AopUtils.isCglibProxy(orderService); //cglib
        boolean isJDKDynamicProxy =  AopUtils.isJdkDynamicProxy(orderService); //jdk动态代理
        LOGGER.info("事物测试:isAopProxy" + isAopProxy + ";isCglibProxy=" + isCglibProxy + "isJDKDynamicProxy;" + isJDKDynamicProxy);

        //如果事物开启了，断点就不会进入，service的方法
        orderService.testTransactionals();

        LOGGER.info("事物测试 end");

        xr.setObject("ok");
        return xr;
    }
}

